package com.glela.live.service.impl;

import com.alibaba.fastjson.JSON;
import com.glela.cache.model.RedisKey;
import com.glela.cache.redis.RedisKeys;
import com.glela.cache.redis.RedisUtil;
import com.glela.common.util.DateUtil;
import com.glela.common.util.JsonUtil;
import com.glela.goods.mapper.GoodsMapper;
import com.glela.goods.mapper.GoodsNavigateMapper;
import com.glela.goods.model.Goods;
import com.glela.goods.model.GoodsNavigate;
import com.glela.goods.model.GoodsPrice;
import com.glela.goods.model.vo.goods.GoodsListResponse;
import com.glela.goods.model.vo.goods.LiveSaleResponse;
import com.glela.goods.service.GoodsService;
import com.glela.goods.service.InventoryService;
import com.glela.live.mapper.LiveSaleGoodsMapper;
import com.glela.live.model.LivePlan;
import com.glela.live.service.LivePlanService;
import com.glela.live.service.LiveSaleGoodsService;
import com.glela.platform.model.User;
import com.glela.platform.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class LiveSaleGoodsServiceImpl implements LiveSaleGoodsService {

    @Autowired
    private LiveSaleGoodsMapper liveSaleGoodsMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private InventoryService inventoryService;

    @Autowired
    private GoodsNavigateMapper goodsNavigateMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private LivePlanService livePlanService;

    private static Logger logger = LoggerFactory.getLogger(LiveSaleGoodsServiceImpl.class);

    @Override
    public List<LiveSaleResponse> getLiveSaleByLivePlanId(int planId) {
        LivePlan livePlan = livePlanService.getById(planId);
        if (redisUtil.get(RedisKeys.LIVE_SALE_GOODS_EXPIRE+livePlan.getId())!=null){
            int size = Integer.valueOf(redisUtil.get(RedisKeys.LIVE_SALE_GOODS_LENGTH+livePlan.getId()));
            List<String> redislist = redisUtil.lrange(RedisKeys.LIVE_SALE_GOODS+planId,0,size-1);
            List<LiveSaleResponse> list = new ArrayList<>();
            if (!redislist.isEmpty()){
                for(String p : redislist) {
                    LiveSaleResponse goodsListResponse = JSON.parseObject(p,LiveSaleResponse.class);
                    list.add(goodsListResponse);
                }
            }
            return list;
        }else{
            //不存在长度说明为第一次请求走正常查询流程查库
            List<LiveSaleResponse> list = new ArrayList<>();
            if (redisUtil.get(RedisKeys.LIVE_SALE_GOODS_LENGTH+livePlan.getId())==null){
                list = getList(livePlan.getId());
                String[] toBeStored = new String[list.size()];
                for (int k = 0; k <list.size() ; k++) {
                    try {
                        toBeStored[k]= JsonUtil.toJson(list.get(k));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
//            redisUtil.del(RedisKeys.LIVE_SALE_GOODS+livePlan.getId());
                redisUtil.set(RedisKeys.LIVE_SALE_GOODS_LENGTH+livePlan.getId(),toBeStored.length);
                redisUtil.rpush(RedisKeys.LIVE_SALE_GOODS+livePlan.getId(),toBeStored);
                redisUtil.set(RedisKeys.LIVE_SALE_GOODS_EXPIRE+livePlan.getId(),"1", 300);
                return list;
            }else {
                //存在长度走异步线程更新
                int size = Integer.valueOf(redisUtil.get(RedisKeys.LIVE_SALE_GOODS_LENGTH+livePlan.getId()));
                if (size==0){
                    redisUtil.set(RedisKeys.LIVE_SALE_GOODS_EXPIRE+livePlan.getId(),"1", 300);
                }else{
                    List<String> redislist = redisUtil.lrange(RedisKeys.LIVE_SALE_GOODS+planId,0,size-1);
                    if (!redislist.isEmpty()){
                        for(String p : redislist) {
                            LiveSaleResponse goodsListResponse = JSON.parseObject(p,LiveSaleResponse.class);
                            list.add(goodsListResponse);
                        }
                    }
                    cacheStoreList(planId,size);
                }
                return list;
            }
        }
        /*

        if (!redislist.isEmpty()){
            for(String p : redislist) {
                LiveSaleResponse goodsListResponse = JSON.parseObject(p,LiveSaleResponse.class);
                list.add(goodsListResponse);
            }
        }else {

        }
        return list;*/
    }

    private List<LiveSaleResponse> getList(int planId){
        List<LiveSaleResponse> list = new ArrayList<>();
        List<Goods> listGoods = liveSaleGoodsMapper.getLiveSaleGoodsByLiveUid(planId);
        if (listGoods == null || listGoods.size() == 0) {
            return list;
        }
        User user = userService.getUserById(Long.valueOf(planId));
        List<Long> goodsIds = new ArrayList<Long>();
        for (Goods goods : listGoods) {
            goodsIds.add(goods.getId());
        }
        Map<Long, GoodsPrice> goodsPriceMap = this.goodsService.getGoodsViewPriceForGoods(user, goodsIds);
//            Map<Long, Long> inventoryMap = this.inventoryService.findDynaByGoodsId(goodsIds);
        int i = 0;
        for (Goods goods : listGoods) {
            try {
                LiveSaleResponse liveSaleResponse = new LiveSaleResponse();
                //GoodsListResponse goodsListResponse = new GoodsListResponse();
                liveSaleResponse.setGoodId(goods.getId());
                liveSaleResponse.setGoodsName(goods.getName());
                    /*goodsListResponse.setGoodId(goods.getId());
                    goodsListResponse.setLabelName(goods.getLabelName());
                    goodsListResponse.setGoodsName(goods.getName());
                    goodsListResponse.setName(goods.getName());
                    goodsListResponse.setTitle(goods.getTitle());
                    goodsListResponse.setSuggestedPrice(goods.getSuggestedPrice());
                    if (!StringUtils.isBlank(goods.getGoodsWidthPic())) {
                        liveSaleResponse.setGoodNavigateImage(goods.getGoodsWidthPic());
                    } else {*/
                //                    logger.info("service:============================开始第："+i+"次循环查询介绍图==================storeUserId:"+storeUserId);
                //                    long navigateTime = System.currentTimeMillis();
                List<GoodsNavigate> goodsNavigateList = this.goodsNavigateMapper.selectGoodsNavigateByGoodId(goods.getId());
                //                    logger.info("service:============================第："+i+"次循环查询介绍图结束耗时："+(System.currentTimeMillis()-navigateTime)+"==================storeUserId:"+storeUserId);
                liveSaleResponse.setGoodNavigateImage(goodsNavigateList.get(0).getNavigateImage());
                   /* }*/
                    /*goodsListResponse.setBrandName("");
                    goodsListResponse.setSelfSupport(goods.getSelfSupport());*/
                //价格信息
                //                logger.info("service:============================开始第："+i+"次循环查询价格==================storeUserId:"+storeUserId);
                //                long goodsPriceTime = System.currentTimeMillis();
                GoodsPrice goodsPrice = goodsPriceMap.get(goods.getId()) == null ? this.goodsService.getGoodsViewPriceForGoods(user, goods.getId()) : goodsPriceMap.get(goods.getId());
                //                logger.info("service:============================第："+i+"次循环查询价格结束耗时："+(System.currentTimeMillis()-goodsPriceTime)+"==================storeUserId:"+storeUserId);
                String nowTime = DateUtil.currentStringDate();
                //商品标签
                List<Map<String, String>> labelArray = new ArrayList<Map<String, String>>();
                // 状态（SecKill:秒杀中;NormalSale:原价销售;PreHeat:预热中;UnderCarriage:下架了）
                // 原价销售：没有参与分时抢购活动，且未被下架。--默认
                // 预热中：分时抢购活动，且服务器当前时间小于秒杀活动开始时间；
                // 秒杀中：分时抢购活动，且服务器当前时间大于秒杀活动开始时间，小于秒杀活动结束时间；
                // 抢光：分时抢购活动，且APP实际库存与分时抢购活动设置的库存中的最小的一个数量小于等于0；
                // 下架：商品下架时间小于服务器当前时间或者下架时间字段为空值；
                String saleStatus = "NormalSale";// 默认原价销售状态
                //存在goodsPrice对象为null的情况
                if (goodsPrice != null) {
                    Long productId = goodsPrice.getProductId();
                    // 查询是否存在分时抢购活动
                    //                    logger.info("service:============================开始第："+i+"次循环查询分时抢购信息==================storeUserId:"+storeUserId);
                    //                    long limitTime = System.currentTimeMillis();
                    Map<String, Object> ltsMap = this.goodsMapper.selectNearlyLimitTimeSale(goods.getId(), productId, nowTime);
                    //                    logger.info("service:============================第："+i+"次循环查询分时抢购信息结束耗时:"+(System.currentTimeMillis()-limitTime)+"==================storeUserId:"+storeUserId);
                    if (ltsMap != null) {
                        Map<String, String> tmLabel = new HashMap<String, String>();
                        // 分时抢购开始时间
                        try {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Date fullBeginTime = sdf.parse(ltsMap.get("fullBeginTime").toString());
                            // 系统当前时间
                            long nowTimeMillis = System.currentTimeMillis();
                            if (fullBeginTime.getTime() > nowTimeMillis) {// 预热中
                                saleStatus = "PreHeat";
                                tmLabel.put("label", "预热");
                            } else {// 抢购中
                                saleStatus = "SecKill";
                                tmLabel.put("label", "特卖");
                            }
                        } catch (ParseException e) {

                        }
                        tmLabel.put("color", "#ff4b7a");
                        labelArray.add(tmLabel);
                    }
                }
                // 实时库存
                //                logger.info("service:============================开始第："+i+"次循环查询实时库存==================storeUserId:"+storeUserId);
                //                long invenTime = System.currentTimeMillis();
                //long realTimeInventory = inventoryMap.get(goods.getId()) == null ? 0 : inventoryMap.get(goods.getId());//this.inventoryService.findDynaByGoodsId(goods.getId()):inventoryMap.get(goods.getId());
                //                logger.info("service:============================第："+i+"次循环查询实时库存结束耗时："+(System.currentTimeMillis()-invenTime)+"==================storeUserId:"+storeUserId);
                // 下架了
                if (goods.getOnlineTime() == null ||
                        goods.getOfflineTime() == null ||
                        (DateUtil.betweenTime(goods.getOnlineTime(), goods.getOfflineTime()) < 1)) {
                    saleStatus = "UnderCarriage";
                }
                // C区商品  设置为已下架状态
                if (goods.getGoodsType() == 0) {
                    saleStatus = "UnderCarriage";
                }
                //goodsListResponse.setSaleStatus(saleStatus);// 销售状态
                liveSaleResponse.setSalePrice(goodsPrice.getSalePrice());// 价格信息
                    /*goodsListResponse.setInventoryNum(realTimeInventory);// 库存数
                    goodsListResponse.setSalerNums(goods.getUpCount());
                    goodsListResponse.setLabelArray(labelArray);// 标签信息*/
                liveSaleResponse.setCommission(goodsPrice.getCommission());
                list.add(liveSaleResponse);
                i++;
            } catch (Exception e) {
                logger.error("=============== 查询直播商品信息异常：{}",e);
                continue;
            }
        }
        return list;
    }

    private static ExecutorService executorService	= Executors.newFixedThreadPool(20);

    public void cacheStoreList(final int planId, final int size) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                List<LiveSaleResponse> list = getList(planId);
                String[] toBeStored = new String[list.size()];
                for (int i = 0; i <list.size() ; i++) {
                    try {
                        toBeStored[i]=JsonUtil.toJson(list.get(i));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                redisUtil.reloadList(RedisKeys.LIVE_SALE_GOODS+planId,size,toBeStored);
                redisUtil.set(RedisKeys.LIVE_SALE_GOODS_EXPIRE+planId,"1", 300);
            }
        });
    }
}
